package userInterface.imageCapture;

import logging.*;
import robot.*;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;

/**
 * A confirmation {@link javax.swing.JDialog JDialog} for the user-selected segment defined in {@link userInterface.imageCapture.DialogCaptureOverlay DialogCaptureOverlay}.
 * @author BDS
 */
class DialogCaptureConfirmation extends JDialog
{
    private static final long serialVersionUID = 1L;

    private ActionListener captureConfirmationActionListener;

    private JPanel pnlCaptureConfirmation;
    private GridBagLayout gblCaptureConfirmation;

    private JLabel lblTitle;
    private JLabel lblImage;
    private JLabel lblName;
    private JLabel lblVisibleInstances;
    private JFormattedTextField txtName;
    private JLabel lblVisibleInstanceCount;

    private JButton btnSave;
    private JButton btnCancel;

    private BufferedImage capturedImage;
    private String capturedImageName;

    /**
     * Class constructor.
     * @param capturedImage The image captured via user input from {@link userInterface.imageCapture.DialogCaptureOverlay DialogCaptureOverlay}.
     */
    public DialogCaptureConfirmation(BufferedImage capturedImage)
    {
        captureConfirmationActionListener = new CaptureConfirmationActionListener();

        setUndecorated(true);
        setAlwaysOnTop(true);
        setModal(true);
        
        pnlCaptureConfirmation = new JPanel();
        pnlCaptureConfirmation.setBorder(BorderFactory.createLineBorder(Color.black));
        getContentPane().add(pnlCaptureConfirmation);
        
        gblCaptureConfirmation = new GridBagLayout();
        gblCaptureConfirmation.columnWeights = new double[] { 0.0, 1.0, 0.0, 0.0 };
        gblCaptureConfirmation.rowWeights = new double[] { 0.0, 1.0, 0.0, 0.0 };
        pnlCaptureConfirmation.setLayout(gblCaptureConfirmation);
                        
        lblTitle = new JLabel("Save Captured Image");
        lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
        lblTitle.setFont(new Font(lblTitle.getFont().getName(), Font.BOLD, 12));
        GridBagConstraints gbc_lblTitle = new GridBagConstraints();
        gbc_lblTitle.fill = GridBagConstraints.BOTH;
        gbc_lblTitle.insets = new Insets(10, 10, 10, 10);
        gbc_lblTitle.gridwidth = 4;
        gbc_lblTitle.gridx = 0;
        gbc_lblTitle.gridy = 0;
        pnlCaptureConfirmation.add(lblTitle, gbc_lblTitle);
                                
        lblImage = new JLabel();
        lblImage.setHorizontalAlignment(SwingConstants.CENTER);
        lblImage.setIcon(new ImageIcon(capturedImage));
        GridBagConstraints gbc_lblImage = new GridBagConstraints();
        gbc_lblImage.fill = GridBagConstraints.BOTH;
        gbc_lblImage.insets = new Insets(0, 10, 5, 10);
        gbc_lblImage.gridwidth = 4;
        gbc_lblImage.gridx = 0;
        gbc_lblImage.gridy = 1;
        pnlCaptureConfirmation.add(lblImage, gbc_lblImage);
                                                
        lblName = new JLabel("Name:");
        GridBagConstraints gbc_lblName = new GridBagConstraints();
        gbc_lblName.anchor = GridBagConstraints.WEST;
        gbc_lblName.insets = new Insets(0, 10, 5, 5);
        gbc_lblName.gridx = 0;
        gbc_lblName.gridy = 2;
        pnlCaptureConfirmation.add(lblName, gbc_lblName);
                                                        
        txtName = new JFormattedTextField();
        GridBagConstraints gbc_txtName = new GridBagConstraints();
        gbc_txtName.fill = GridBagConstraints.HORIZONTAL;
        gbc_txtName.insets = new Insets(0, 0, 5, 10);
        gbc_txtName.gridwidth = 3;
        gbc_txtName.gridx = 1;
        gbc_txtName.gridy = 2;
        pnlCaptureConfirmation.add(txtName, gbc_txtName);
                                                                
        lblVisibleInstances = new JLabel("Visible instances:");
        GridBagConstraints gbc_lblVisibleInstances = new GridBagConstraints();
        gbc_lblVisibleInstances.anchor = GridBagConstraints.WEST;
        gbc_lblVisibleInstances.insets = new Insets(0, 10, 5, 5);
        gbc_lblVisibleInstances.gridx = 0;
        gbc_lblVisibleInstances.gridy = 3;
        pnlCaptureConfirmation.add(lblVisibleInstances, gbc_lblVisibleInstances);
                                                                        
        lblVisibleInstanceCount = new JLabel();
        GridBagConstraints gbc_lblVisibleInstanceCount = new GridBagConstraints();
        gbc_lblVisibleInstanceCount.fill = GridBagConstraints.HORIZONTAL;
        gbc_lblVisibleInstanceCount.insets = new Insets(0, 0, 5, 10);
        gbc_lblVisibleInstanceCount.gridwidth = 3;
        gbc_lblVisibleInstanceCount.gridx = 1;
        gbc_lblVisibleInstanceCount.gridy = 3;
        pnlCaptureConfirmation.add(lblVisibleInstanceCount, gbc_lblVisibleInstanceCount);
        
        btnSave = new JButton("Save");
        btnSave.setMnemonic(KeyEvent.VK_S);
        btnSave.setActionCommand("Save");
        btnSave.addActionListener(captureConfirmationActionListener);
        GridBagConstraints gbc_btnSave = new GridBagConstraints();
        gbc_btnSave.anchor = GridBagConstraints.EAST;
        gbc_btnSave.insets = new Insets(0, 0, 10, 5);
        gbc_btnSave.gridx = 2;
        gbc_btnSave.gridy = 4;
        pnlCaptureConfirmation.add(btnSave, gbc_btnSave);
                                                                                        
        btnCancel = new JButton("Cancel");
        btnCancel.setMnemonic(KeyEvent.VK_C);
        btnCancel.setActionCommand("Cancel");
        btnCancel.addActionListener(captureConfirmationActionListener);
        GridBagConstraints gbc_btnCancel = new GridBagConstraints();
        gbc_btnCancel.anchor = GridBagConstraints.EAST;
        gbc_btnCancel.insets = new Insets(0, 0, 10, 10);
        gbc_btnCancel.gridx = 3;
        gbc_btnCancel.gridy = 4;
        pnlCaptureConfirmation.add(btnCancel, gbc_btnCancel);

        // TODO Wait cursor is not rendering properly.
        try
        {
            setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            
            int visibleInstances = new ExecutionRobot().checkVisibleInstances(capturedImage);
            
            if (visibleInstances >= 10)
            {
                lblVisibleInstanceCount.setText(String.format("%d+", visibleInstances));
            }
            else
            {
                lblVisibleInstanceCount.setText(Integer.toString(visibleInstances));
            }
            
            if (visibleInstances > 1)
            {
                lblVisibleInstanceCount.setForeground(Color.ORANGE);
            }
        }
        catch (Exception exception)
        {
            lblVisibleInstances.setVisible(false);
            lblVisibleInstanceCount.setVisible(false);
            Logger.logException(exception);
        }
        finally
        {
            setCursor(Cursor.getDefaultCursor());
        }
        
        // Center on the screen.
        pack();
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setLocation(screenSize.width / 2 - getSize().width / 2, screenSize.height / 2 - getSize().height / 2);

        this.capturedImage = capturedImage;
        capturedImageName = null;
    }

    /**
     * Gets the filename of the captured image.
     * @return The filename of the captured image.
     */
    public String getCapturedImageName()
    {
        return capturedImageName;
    }

    /**
     * {@link java.awt.event.ActionListener ActionListener} for {@link userInterface.imageCapture.DialogCaptureConfirmation DialogCaptureConfirmation} {@link javax.swing.JFormattedTextField JFormattedTextFields}.
     * @author BDS
     */
    private class CaptureConfirmationActionListener implements ActionListener
    {
        /**
         * Executes specific logic based on the following {@link java.awt.event.ActionEvent ActionEvents}:
         * <ul>
         *     <li>Save - Stores the provided image name and closes the dialog.</li>
         *     <li>Cancel - Closes the dialog.</li>
         * </ul>
         * @param actionEvent The triggering {@link java.awt.event.ActionEvent ActionEvent}.
         */
        @Override
        public void actionPerformed(ActionEvent actionEvent)
        {
            if (actionEvent.getActionCommand().equals(btnSave.getActionCommand()))
            {
                capturedImageName = txtName.getText();

                try
                {
                    ImageIO.write(capturedImage, "png", new File(String.format("%s\\Images\\%s.png", System.getProperty("user.dir"), capturedImageName)));

                    setVisible(false);
                }
                catch (IOException exception)
                {
                    JOptionPane.showMessageDialog(null, exception.getMessage(), "Image not saved", JOptionPane.ERROR_MESSAGE);
                    capturedImageName = null;
                }
            }
            else if (actionEvent.getActionCommand().equals(btnCancel.getActionCommand()))
            {
                capturedImageName = null;

                setVisible(false);
            }
        }
    }
}
